package us.mooresr.aircraftscheduling.client.ui;

import java.util.ArrayList;
import java.util.List;

import us.mooresr.aircraftscheduling.client.LoginStateManager;
import us.mooresr.aircraftscheduling.client.events.UserChangedEvent;
import us.mooresr.aircraftscheduling.client.events.UserChangedEvent.UserChangedHandler;
import us.mooresr.aircraftscheduling.client.events.UserCreatedEvent;
import us.mooresr.aircraftscheduling.client.events.UserCreatedEvent.UserCreatedHandler;
import us.mooresr.aircraftscheduling.client.events.UserDeletedEvent;
import us.mooresr.aircraftscheduling.client.events.UserDeletedEvent.UserDeletedHandler;
import us.mooresr.aircraftscheduling.shared.model.Reservation;
import us.mooresr.aircraftscheduling.shared.model.User;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.AbstractSafeHtmlCell;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.cell.client.CompositeCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.HasCell;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.text.shared.SafeHtmlRenderer;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.ViewWithUiHandlers;
import com.google.gwt.view.client.ProvidesKey;

public class UserListView extends ViewWithUiHandlers<UserListUiHandlers> 
	implements UserListPresenter.MyView {
	
	private final HTMLPanel widget;
	private final LoginStateManager loginStateManager;

	public interface Binder extends UiBinder<HTMLPanel, UserListView> {
		
	}
	
	@UiField(provided = true)
	CellTable<User> cellTable;
	
	private ListDataProvider<User> dataProvider = new ListDataProvider<User>();
	
	@Inject
	public UserListView(final Binder binder, final EventBus eventBus, 
			final LoginStateManager loginStateManager) {
		
		this.loginStateManager = loginStateManager;
		
		cellTable = new CellTable<User>();
		
		setupTableColumns();
		
		dataProvider.addDataDisplay(cellTable);
		
		eventBus.addHandler(UserCreatedEvent.getType(), new UserCreatedHandler() {

			@Override
			public void onUserCreated(UserCreatedEvent event) {
				List<User> list = dataProvider.getList();
				list.add(event.getUser());
				
			}
			
		});
		
		eventBus.addHandler(UserDeletedEvent.getType(), new UserDeletedHandler() {

			@Override
			public void onUserDeleted(UserDeletedEvent event) {
				List<User> list = dataProvider.getList();
				for (User u : list) {
					if (u.getUserId() == event.getUser().getUserId()) {
						list.remove(u);
						break;
					}
				}
				
			}
			
		});
		
		eventBus.addHandler(UserChangedEvent.getType(), new UserChangedHandler() {

			@Override
			public void onUserChanged(UserChangedEvent event) {
				List<User> list = dataProvider.getList();
				for (User u : list) {
					if (u.getUserId() == event.getUser().getUserId()) {
						list.remove(u);
						list.add(event.getUser());
						break;
					}
				}
				
			}
			
		});
		
		widget = binder.createAndBindUi(this);
	}
	
	private class AdminOnlyButton extends ButtonCell {
		
		private LoginStateManager loginStateManager;
		
		@Inject
		public AdminOnlyButton(LoginStateManager loginStateManager) {
			super();
			
			this.loginStateManager = loginStateManager;
		}

		@Override
		public void render(Context context, SafeHtml data, SafeHtmlBuilder sb) {
			
			
			if (loginStateManager.isAdmin()) {
				sb.appendHtmlConstant("<button type=\"button\" tabindex=\"-1\">");
				if (data != null) {
					sb.append(data);
				}
				sb.appendHtmlConstant("</button>");
			}
		}
	}

	private void setupTableColumns() {
		TextColumn<User> nameColumn = new TextColumn<User>() {

			@Override
			public String getValue(User object) {
				return object.getName();
			}
		};
		cellTable.addColumn(nameColumn, "Name");
		
		ButtonCell editCell = new ButtonCell();
		Column<User, String> editColumn = new Column<User, String>(editCell) {

			@Override
			public String getValue(User object) {
				if (loginStateManager.canEdit(object)) {
					return "Edit";
				} else {
					return "View";
				}

			}
			
		};
		
		editColumn.setFieldUpdater(new FieldUpdater<User, String>() {
			@Override
			public void update(int index, User object, String value) {
				if (loginStateManager.canEdit(object)) {
					getUiHandlers().editUser(object);
				} else {
					getUiHandlers().viewUser(object);
				}
			}
			
		});

		
		AdminOnlyButton deleteCell = new AdminOnlyButton(loginStateManager);
		Column<User, String> deleteColumn = new Column<User, String>(deleteCell) {

			@Override
			public String getValue(User object) {
				return "Delete";
			}
			

			

		};
		
		deleteColumn.setFieldUpdater(new FieldUpdater<User, String>() {

			@Override
			public void update(int index, User object, String value) {
				if (Window.confirm("Are you sure you want to delete " + object.getName())) {
					getUiHandlers().deleteUser(object);
				}
				
			}
			
		});

		
		
		ArrayList<HasCell<User, ?>> columnList = new ArrayList<HasCell<User, ?>>();
		columnList.add(editColumn);
		columnList.add(deleteColumn);
		
		CompositeCell<User> compositeCell = new CompositeCell<User>(columnList);
		
		Column compositeColumn = new Column(compositeCell) {

			@Override
			public Object getValue(Object object) {
				// TODO Auto-generated method stub
				return object;
			}

	
			
		};
		

		
		cellTable.addColumn(compositeColumn, "Actions");
		
	}

	@Override
	public Widget asWidget() {
		return widget;
	}
	
	@UiHandler("createButton")
	void onCreateClicked(ClickEvent event) {
		getUiHandlers().createUser();
		
	}

	@Override
	public void setData(ArrayList<User> userList) {

		
		List<User> list = dataProvider.getList();
		
		list.clear();
		
		for (User r : userList) {
			list.add(r);
		}
		
		
		render();
		
	}

	private void render() {
		// TODO Re-render the table.  Do we need to do anything here?
		
	}

}
